package com.base.pub.persistence.tenant;

import java.util.HashMap;
import java.util.Map;

import javax.naming.CompositeName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;

import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.c3p0.internal.C3P0ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;

public class SchemaMultiTenantConnectionProvider extends
		AbstractMultiTenantConnectionProvider implements
		ApplicationContextAware {

	private static ApplicationContext context = null;

	public SchemaMultiTenantConnectionProvider() throws NamingException {
		dbSourceContext = new InitialContext();
		jndiName = new CompositeName(JNDINAME);
	}

	Context dbSourceContext;
	String JNDINAME = "java:comp/env/jdbc/sys";
	Name jndiName;

	@Override
	protected ConnectionProvider getAnyConnectionProvider() {
		C3P0ConnectionProvider defaultProvier = new C3P0ConnectionProvider();
		defaultProvier
				.injectServices((ServiceRegistryImplementor) getServiceRegistry());
		defaultProvier.configure(getConfig());

		return defaultProvier;
	}

	@Override
	protected ConnectionProvider selectConnectionProvider(
			String tenantIdentifier) {
		C3P0ConnectionProvider defaultProvier = new C3P0ConnectionProvider();
		defaultProvier
				.injectServices((ServiceRegistryImplementor) getServiceRegistry());
		defaultProvier.configure(getConfig());

		return defaultProvier;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		context = applicationContext;
	}

	private Map getConfig() {
		LocalSessionFactoryBean sessionFactoryBean = context
				.getBean(LocalSessionFactoryBean.class);
		Map<String, String> result = new HashMap<String, String>();
		result.putAll((Map) sessionFactoryBean.getHibernateProperties());
		return result;
	}

	private ServiceRegistry getServiceRegistry() {
		LocalSessionFactoryBean sessionFactoryBean = context
				.getBean(LocalSessionFactoryBean.class);
		StandardServiceRegistry serviceRegistry = sessionFactoryBean
				.getObject().getSessionFactoryOptions().getServiceRegistry();
		return serviceRegistry;
	}

}
